Skip to content

refactor: name the game->menu state machine - #7

Merged
Periicles merged 1 commit into
mainfrom
feat/menu-state-machine
Jun 16, 2026
Merged

refactor: name the game->menu state machine#7
Periicles merged 1 commit into
mainfrom
feat/menu-state-machine

Conversation

@Periicles

Copy link
Copy Markdown
Owner

Why

game->menu is a stack of menu screens encoded in base 10 — menu = menu * 10 + N
pushes a screen, menu /= 10 pops. Every one of the ~80 call sites read or wrote
that as raw decimal arithmetic (menu % 10 == 6, (menu / 10) % 10 != 6,
menu * 10 + 6, menu <= 563, ...), which was unreadable and a classic source of
navigation bugs.

What

New menu.h / menu.c:

  • State constants: MENU_START, MENU_GAME, MENU_WIN, MENU_LOSE,
    MENU_SETTINGS, MENU_PAUSE_INVENTORY/CHARACTER/QUEST/SETTINGS, SCREEN_*.
  • Transitions: menu_push, menu_pop, menu_set_tab.
  • Predicates: menu_is_start, menu_in_overworld, menu_show_hud,
    menu_pause_open, menu_pause_active, menu_in_pause_tab,
    menu_tab_inventory/character/quest, menu_in_settings, menu_settings_open,
    menu_tab_fps/music/keyboard/window, menu_won, menu_lost.

Every helper reproduces the exact original expression, so this is a pure
readability pass with no behavioural change. A reverse-engineered map of the
state machine was used to do the translation faithfully.

The decoded state machine is documented in the PR discussion below for reviewers.

Scope

Naming only — the underlying base-10 encoding is preserved. A full re-encoding to
an explicit enum + stack is deliberately left as a follow-up, since it would change
the encoding and can only be validated by playing through the menus.

Verification

  • make re: warning-free.
  • Banana: full scan still 0 findings.
  • make tests_run: 10/10 passing.

A couple of bare comparisons remain (menu > 500, menu <= 563): these are
encoding thresholds inside already-named transition functions and don't map onto a
clean predicate.

game->menu is a stack of screens encoded in base 10 (menu = menu * 10 + N
pushes a screen, menu /= 10 pops). Every call site read or wrote that as
raw decimal arithmetic (menu % 10 == 6, (menu / 10) % 10 != 6,
menu * 10 + 6, ...), which was unreadable and error-prone.

Introduce menu.h/menu.c: named state constants (MENU_START, MENU_GAME,
MENU_WIN, MENU_PAUSE_*, ...), transition helpers (menu_push, menu_pop,
menu_set_tab) and predicate helpers (menu_in_overworld, menu_pause_open,
menu_tab_music, menu_won, ...). Each helper reproduces the original
expression exactly, so behaviour is unchanged — this is a pure
readability pass. The remaining bare comparisons are encoding thresholds
inside already-named functions.

Verified: build warning-free, full Banana scan still 0 findings, the
criterion suite still passes 10/10.
@Periicles
Periicles merged commit 21e2897 into main Jun 16, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant